#include "oopoperation.h"

oopOperation::oopOperation(QWidget *parent)
    : QWidget{parent}
{
    itemRead = new QPushButton(tr("召测"));
    itemSend = new QPushButton(tr("设置"));
    passwordInput = new QLineEdit();
    paramList = new QListWidget();
    stack = new QStackedLayout();
    paramBLEupdate = new QListWidgetItem();
    paramBLEupdate->setText(tr("蓝牙升级"));
    paramBLEupdateWidgetInit();

    paramList->addItem(paramBLEupdate);
    stack ->addWidget(paramBLEupdateWidget);

    CtrlbuttonLayout = new QHBoxLayout();
    setItemLayout = new QHBoxLayout();
    setMainLayout  = new QVBoxLayout();

     CtrlbuttonLayout->addWidget(itemRead);
     CtrlbuttonLayout->addWidget(itemSend);
     CtrlbuttonLayout->addWidget(passwordInput);
     CtrlbuttonLayout->addStretch(3); //设置弹簧

     setItemLayout->addWidget(paramList);
     setItemLayout->addLayout(stack);
     setItemLayout->setStretchFactor(paramList,1);
     setItemLayout->setStretchFactor(stack,3);
     setMainLayout->addLayout(CtrlbuttonLayout);
     setMainLayout->addLayout(setItemLayout);

     setLayout(setMainLayout);   //展示界面。
     resize(1000,500);
     setWindowTitle("OOP协议操作包括蓝牙升级");
     qDebug()<<"set AA";
    intoUpdateState =0xAA;
     timerUpdate = startTimer(1000*5);

     this->setAttribute(Qt::WA_QuitOnClose, false);
}
 void oopOperation::updatePageShowSlot()
 {
     INT16S pos=-1;
    qDebug()<<"heihiehie"<<"intoUpdateState is "<<hex<<intoUpdateState;
     if((pos = str_find((INT8U*)serial_channel.recevice_frame_waite,serial_channel.receive_len,(const INT8U *)"\xF2\x0B\x02\x01\x01",5))>-1)
     {
         if((pos = str_find((INT8U*)serial_channel.recevice_frame_waite,serial_channel.receive_len,(const INT8U *)"\x06\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x68",15))>-1)
         {
             if(intoUpdateState ==0xBB)
             {
                  nowPacketNum++;
             }
             if(intoUpdateState ==0xAA)
             {
                intoUpdateState =0xBB;
                nowPacketNum=0;
             }
             if(intoUpdateState ==0xDD)
             {
                   qDebug()<< "update ok";
                   return;
             }
            qDebug()<< "judge pass"<<"intoUpdateState is "<<hex<<intoUpdateState;
             make_376update_frame();
         }
     }
    memset((INT8U*)serial_channel.recevice_frame_waite,0,RECE_FRAME_LEN);
    serial_channel.receive_len =0;
 }
void  oopOperation::paramBLEupdateWidgetInit()  // 蓝牙升级界面初始化。
{
    paramBLEupdateWidget = new QWidget();
    UpdateBLEGridLayout = new QGridLayout();
    UpdateBLEFilePathLabel = new QLabel(tr("升级文件路径"));
    UpdateBLEFileButton = new QPushButton(tr("打开升级文件"));
    UpdateBLEFilePath_Edit  =new QLineEdit();
    UpdateBLEStart= new QPushButton(tr("开始升级"));
    UpdateBLEEnd= new QPushButton(tr("结束/清除升级"));
    progressbar = new QProgressBar();
    progressbar->setRange(0,100);
    progressbar->setValue(0);
    UpdateBLEGridLayout->addWidget(UpdateBLEFilePathLabel,0,0);
    UpdateBLEGridLayout->addWidget(UpdateBLEFilePath_Edit,0,1);
    UpdateBLEGridLayout->addWidget(UpdateBLEFileButton,1,1);
    UpdateBLEGridLayout->addWidget(UpdateBLEStart,2,0);
    UpdateBLEGridLayout->addWidget(UpdateBLEEnd,2,1);
    UpdateBLEGridLayout->addWidget(progressbar,3,0,1,4);
    UpdateBLEGridLayout->setColumnStretch(4,2);
    UpdateBLEGridLayout->setRowStretch(4,2);
    paramBLEupdateWidget->setLayout(UpdateBLEGridLayout);
    connect(UpdateBLEFileButton,SIGNAL(clicked()),this,SLOT(update_file_broswer_slot()));

    connect(UpdateBLEStart,SIGNAL(clicked()),this,SLOT(update_start_slot()));
    connect(UpdateBLEEnd,SIGNAL(clicked()),this,SLOT(update_close_slot()));
}
void oopOperation::update_file_broswer_slot()
{
    INT8U buf[1024]={0};
    INT8U resp[1024]={0};
    INT16U respLen =0;
//    INT32U BLEUpdateFIleCRC=0;
    UpdateBLEFilePath_Edit->clear();
    fileName.clear();
    updateFileLen =0;
    fileName = QFileDialog::getOpenFileName(
        this,
        tr("浏览升级文件"),
        "D:/",
        tr("updatefile(*.dat);;images(*.png *jpeg *bmp);;video files(*.avi *.mp4 *.wmv);;All files(*.*)"));
    if (fileName.isEmpty()) {
        QMessageBox::warning(this, "Warning!", "升级文件没有找到");
    }
    else{
        memcpy(buf,"\xFE\xFE\xFE\xFE\x68\x17\x00\x43\x15\x85\x31\x07\x25\x04\x23\xA0\xA7\x89\x05\x01\x01\x40\x00\x02\x00\x00\x7D\x1B\x16",29);
       respLen = protocoloop.makeOOP0907UpdateFrame(buf,29,resp);
       UpdateBLEFilePath_Edit->setText(fileName);
        updateFileHandler.setFileName(fileName);
       updateFileHandler.open(QIODevice::ReadOnly);
       QByteArray q = updateFileHandler.readAll();
      // updateFile = (INT8U*) q.data();
       memcpy((INT8U *)updateFile,(INT8U *)q.data(),q.size());
       updateFileLen = q.size();


      BLEUpdateFIleCRC =  code_crc32(updateFile,updateFileLen);
      total_packetNum = (updateFileLen+480-1)/480;
      qDebug()<<"file len is "<<updateFileLen <<"crc res is " <<hex<<BLEUpdateFIleCRC<<"total packet num"<<total_packetNum;
//       file_total_seg = updateFileLen/1024+1;
//       file_cur_seg =0;
//       qDebug()<<"file total seg is "<<file_total_seg;
    }
 }
void oopOperation::make_376update_frame()
{
    objRequest request;
    int update_date_len =1024;
    bool  end_seg=FALSE;
    INT8U bleUpdateBuf[1024]={0};
    INT16U bleUpdateBufPos=0;
    int res_send_len;
    if(intoUpdateState ==0xAA)
    {
    bleUpdateBuf[bleUpdateBufPos++] = 0x68;
    bleUpdateBufPos+=2;
    bleUpdateBuf[bleUpdateBufPos++] = 0x02;
    memcpy(bleUpdateBuf+bleUpdateBufPos,"\x06\xFF\xFF\xFF",4);
    bleUpdateBufPos+=4;
    memcpy(bleUpdateBuf+bleUpdateBufPos,"\xFF\xFF\xFF\xFF\xFF\xFF",6);
    bleUpdateBufPos+=6;
    memcpy(bleUpdateBuf+bleUpdateBufPos,"\x00\x00\x00\x00",4); //预留：默认全为 0
    bleUpdateBufPos+=4;
    bleUpdateBuf[bleUpdateBufPos++] = 0x68;  //应用数据域帧起始符
    bleUpdateBuf[bleUpdateBufPos++] = 0x01;
    bleUpdateBuf[bleUpdateBufPos++] = 0x00;   //操作码 升级开始
    memcpy(bleUpdateBuf+bleUpdateBufPos,"\x00\x00",2); //保留位
    bleUpdateBufPos+=2;
    bleUpdateBuf[bleUpdateBufPos++] = updateFileLen&0xFF;
    bleUpdateBuf[bleUpdateBufPos++] = (updateFileLen>>8)&0xFF;
    bleUpdateBuf[bleUpdateBufPos++] = (updateFileLen>>16)&0xFF;
    bleUpdateBuf[bleUpdateBufPos++] = (updateFileLen>>24)&0xFF;
    memcpy(bleUpdateBuf+bleUpdateBufPos,"\xE0\x01\x00\x00",4);   //默认就420个字节一包
    bleUpdateBufPos+=4;
    memcpy(bleUpdateBuf+bleUpdateBufPos,"\xFF\xFF\xFF\xFF",4);   //工厂 ID 默认 FF FF FF FF
    bleUpdateBufPos+=4;
    bleUpdateBuf[bleUpdateBufPos++] = 0x00;
    bleUpdateBuf[bleUpdateBufPos++] = 0x00;
     bleUpdateBuf[bleUpdateBufPos++] = 0x00;
    bleUpdateBuf[bleUpdateBufPos++] = 0x00;
    memcpy(bleUpdateBuf+bleUpdateBufPos,"\x01\x00\x32\x91",4);   //
    bleUpdateBufPos+=4;
    bleUpdateBuf[bleUpdateBufPos++] = BLEUpdateFIleCRC&0xFF;
    bleUpdateBuf[bleUpdateBufPos++] = (BLEUpdateFIleCRC>>8)&0xFF;
    bleUpdateBuf[bleUpdateBufPos++] = (BLEUpdateFIleCRC>>16)&0xFF;
    bleUpdateBuf[bleUpdateBufPos++] = (BLEUpdateFIleCRC>>24)&0xFF;
    bleUpdateBuf[1] = (bleUpdateBufPos-19)&0xFF;   //有效的数据长度在这里复制
    bleUpdateBuf[2] = ( (bleUpdateBufPos-19)>>8)&0xFF;
   INT8U crc =  crc16_param(bleUpdateBuf,bleUpdateBufPos);
   bleUpdateBuf[bleUpdateBufPos++] =crc;
   bleUpdateBuf[bleUpdateBufPos++] =0x16;
    }
    else if(intoUpdateState ==0xBB)
    {
        bleUpdateBuf[bleUpdateBufPos++] = 0x68;
        bleUpdateBufPos+=2;
        bleUpdateBuf[bleUpdateBufPos++] = 0x02;
        memcpy(bleUpdateBuf+bleUpdateBufPos,"\x06\xFF\xFF\xFF",4);
        bleUpdateBufPos+=4;
        memcpy(bleUpdateBuf+bleUpdateBufPos,"\xFF\xFF\xFF\xFF\xFF\xFF",6);
        bleUpdateBufPos+=6;
        memcpy(bleUpdateBuf+bleUpdateBufPos,"\x00\x00\x00\x00",4); //预留：默认全为 0
        bleUpdateBufPos+=4;
        bleUpdateBuf[bleUpdateBufPos++] = 0x68;  //应用数据域帧起始符
        bleUpdateBuf[bleUpdateBufPos++] = 0x01;
        bleUpdateBuf[bleUpdateBufPos++] = 0x01;   // 操作码 bin 数据传输过程
        memcpy(bleUpdateBuf+bleUpdateBufPos,"\x00\x00",2); //保留位
        bleUpdateBufPos+=2;
        bleUpdateBuf[bleUpdateBufPos++] = total_packetNum&0xFF;  // bin 文件总包数
        bleUpdateBuf[bleUpdateBufPos++] = (total_packetNum>>8)&0xFF;
        bleUpdateBuf[bleUpdateBufPos++] = (total_packetNum>>16)&0xFF;
        bleUpdateBuf[bleUpdateBufPos++] = (total_packetNum>>24)&0xFF;
        bleUpdateBuf[bleUpdateBufPos++] = nowPacketNum&0xFF;   //bin 文件当前包数
        bleUpdateBuf[bleUpdateBufPos++] = (nowPacketNum>>8)&0xFF;
        bleUpdateBuf[bleUpdateBufPos++] = (nowPacketNum>>16)&0xFF;
        bleUpdateBuf[bleUpdateBufPos++] = (nowPacketNum>>24)&0xFF;

        if(nowPacketNum<total_packetNum-1)
        {
              res_send_len =480;
        }
        else
        {
            res_send_len =updateFileLen-nowPacketNum*480;
            intoUpdateState = 0xCC;
        }
         qDebug()<<"total_packetNum is "<<total_packetNum<<"nowPacketNumis "<<nowPacketNum<<"res_send_len is "<<res_send_len<<"intoUpdateState is "<<hex<<intoUpdateState;
        bleUpdateBuf[bleUpdateBufPos++] = res_send_len&0xFF;
        bleUpdateBuf[bleUpdateBufPos++] = (res_send_len>>8)&0xFF;
        memcpy(bleUpdateBuf+bleUpdateBufPos,updateFile+nowPacketNum*480,res_send_len);
        bleUpdateBufPos+=res_send_len;

        bleUpdateBuf[1] = (bleUpdateBufPos-19)&0xFF;   //有效的数据长度在这里复制
        bleUpdateBuf[2] = ( (bleUpdateBufPos-19)>>8)&0xFF;
       INT8U crc =  crc16_param(bleUpdateBuf,bleUpdateBufPos);
       bleUpdateBuf[bleUpdateBufPos++] =crc;
       bleUpdateBuf[bleUpdateBufPos++] =0x16;
    }
    else if(intoUpdateState ==0xCC)   //升级完了，发升级确认帧。
    {
    memcpy(bleUpdateBuf,"\x68\x02\x00\x02\x06\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x68\x01\x02\xD4\x16",23);
    bleUpdateBufPos=23;
      intoUpdateState = 0xDD;
    }
      //发送到串口增加 OOP 0907 报文。
    INT16U respLen = protocoloop.makeOOP0907UpdateFrame(bleUpdateBuf,bleUpdateBufPos,(INT8U*)serial_channel.response_frame);
//    memcpy(serial_channel.response_frame,bleUpdateBuf,bleUpdateBufPos);
    serial_channel.response_len = respLen;
    serial_channel.need_show_flag=1;
    serial_channel.need_show_AFN =0xF;
    emit sendframeSignal_param_page();

}
void oopOperation::update_start_slot()
{
   qDebug()<<"start button ";
   if (updateFileLen !=0) {  //有合法的升级文件
     intoUpdateState =0xAA;
     nowPacketNum =0;
     serial_channel.receive_len =0;
       make_376update_frame();

   }
}
void oopOperation::update_close_slot()
{
   qDebug()<<"close button ";
   file_cur_seg =0;
}
